package cn.good.yan.controller;

import cn.good.yan.entities.PayDTO;
import cn.good.yan.resp.ResultData;
import cn.good.yan.resp.ReturnCodeEnum;
import cn.hutool.core.util.IdUtil;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;


/**
 * 演示：openfeign + sentinel进行服务降级和流量监控的整合处理 --------
 * 需要启动 9001 、 83 、 nacos、 sentinel服务端
 *
 * @author shengren.yan
 * @create 2022-04-06
 */
@RestController
public class SayAlibabaController {


    // 演示：openfeign + sentinel进行服务降级和流量监控的整合处理 --------
    // 需要：在该服务配置流控--- 资源名 sayNo，阈值类型：QPS、阈值：2 ...
    // 访问：http://localhost:9001/say/nacos/111   接口 正常
    @GetMapping(value = "/say/nacos/{orderNo}")
    @SentinelResource(value = "sayNo", blockHandler = "handlerHandler")
    public ResultData<String> sayNo(@PathVariable("orderNo") String orderNo) {
        // 模拟从数据库查询出数据并赋值给DTO
        PayDTO payDTO = new PayDTO();
        payDTO.setId(100);
        payDTO.setOrderNo(orderNo);
        payDTO.setAmount(BigDecimal.valueOf(9.9));
        payDTO.setPayNo("no:" + IdUtil.fastUUID());
        payDTO.setUserId(1);
        return ResultData.success("查询成功ok - 返回值：" + payDTO);
    }

    // 自定义流控 进入的方法
    public ResultData handlerHandler(@PathVariable("orderNo") String orderNo, BlockException exception) {
        return ResultData.fail(
                ReturnCodeEnum.RC500.getCode(), "获取sayNo服务不可用，" + "触发流控配置规则----"
        );
    }

    /*
    fallback服务降级方法纳入到Feign接口统一处理，全局一个 ，这里需要删除掉
    public ResultData myBack(@PathVariable("orderNo") String orderNo,Throwable throwable) {
        return ResultData.fail(ReturnCodeEnum.RC500.getCode(),"异常情况："+throwable.getMessage());
    }
    */


    // 演示：网关与流控的绑定 ， 需要启动 9001 、 9528 、 nacos
    // 访问：http://localhost:9001/say/gateway/1xx  通过9001服务访问，多次访问，没有任何流控
    // 访问：http://localhost:9528/say/gateway/1xx  通过网关访问，多次访问，会被流控，返回自定义的内容  (在网关里配置 GatewayConfiguration)
    // 访问：http://localhost:9528/say/nacos/1xx    通过网关访问，多次访问，会被流控，返回自定义的内容
    @GetMapping(value = "/say/gateway/{orderNo}")
    public ResultData<String> gateway(@PathVariable("orderNo") String orderNo) {
        // 模拟从数据库查询出数据并赋值给DTO
        PayDTO payDTO = new PayDTO();
        payDTO.setId(100);
        payDTO.setOrderNo(orderNo);
        payDTO.setAmount(BigDecimal.valueOf(9.9));
        payDTO.setPayNo("no:" + IdUtil.fastUUID());
        payDTO.setUserId(1);
        return ResultData.success("查询成功ok - 返回值：" + payDTO);
    }

}
